/**
 * Copyright (C), 2017-2018, XXX有限公司
 * FileName: Visitor
 * Author:   zengjian
 * Date:     2018/8/16 11:31
 * Description: 访问接口类
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package org.yinxue.swing.unit.visitor;

import org.yinxue.swing.unit.model.ClassDesc;
import org.yinxue.swing.unit.model.FieldDesc;
import org.yinxue.swing.unit.model.MethodDesc;
import org.yinxue.swing.unit.model.StatementDesc;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

/**
 * 〈访问接口类〉<br>
 * 〈一句话描述〉
 *
 * @author zengjian
 * @create 2018/8/16 11:31
 */
public interface Visitor {

    String visit(ClassDesc classDesc);

    StringBuilder visit(MethodDesc methodDesc);

    StatementUnitContext visit(StatementDesc childMethod);

    void visit(FieldDesc fieldDesc);

    public static class StatementUnitContext {
        StringBuilder variableBuilder;
        StringBuilder invokeBuilder;

        public StatementUnitContext(StringBuilder variableBuilder, StringBuilder invokeBuilder) {
            this.variableBuilder = variableBuilder;
            this.invokeBuilder = invokeBuilder;
        }
    }

    static class ClassUnitContext {
        final StringBuilder unitPackageLine = new StringBuilder(128);
        final StringBuilder unitImportLines = new StringBuilder(1024);
        final StringBuilder unitClassAnnotationLines = new StringBuilder(128);
        final StringBuilder unitClassNameHeader = new StringBuilder(128);
        final StringBuilder unitClassFields = new StringBuilder(256);
        final StringBuilder unitMethodLines = new StringBuilder();
        final StringBuilder unitClassNameFooter = new StringBuilder("}");
        /**
         * 生成测试类导入包
         */
        final Set<String> targetImportLines = new TreeSet<String>();
        final Set<String> targetFieldLines = new TreeSet<>(new Comparator<String>() {
            /**
             * 不能只取长度，只取长度会导致相同长度的节点被覆盖
             * @param o1
             * @param o2
             * @return
             */
            @Override
            public int compare(String o1, String o2) {
                int compare = o1.length() - o2.length();
                if (compare==0){
                    return o1.hashCode() - o2.hashCode();
                }
                return compare;
            }
        });
        /**
         * 需要生成测试类的目标类，结束后置空
         */
        ClassDesc targetClassDesc;

        void reset(){
            this.clear(unitPackageLine);
            this.clear(unitImportLines);
            this.clear(unitClassAnnotationLines);
            this.clear(unitClassNameHeader);
            this.clear(unitClassFields);
            this.clear(unitMethodLines);
            targetImportLines.clear();
            targetClassDesc.tempUnitContext = null;
            targetClassDesc = null;
            targetFieldLines.clear();
        }

        void clear(StringBuilder builder) {
            // builder.delete(0, builder.length())修改，提高效率
            builder.setLength(0);
        }

        ClassUnitContext setClassDesc(ClassDesc targetClassDesc){
            this.targetClassDesc = targetClassDesc;
            targetClassDesc.tempUnitContext = this;
            return this;
        }
    }


}